package com.hktf.corelib.utils;

import java.nio.ByteBuffer;

/**
 * @包名称： com.cdz.bluetooth.util
 * @类名： ByteUtil
 * @创建人： 陈大专
 * @时间： 2021/08/17 11:13
 * @描述：
 */
public class ByteUtil {

    public static String getHexStringNO0x(byte[] data, boolean isBig) {
        String result = "";
        if (data == null) {
            return result;
        }
        int length = data.length;
        if (isBig) {
            result += bytesToHexString(data, length, true);
        } else {
            byte[] temp = new byte[length];
            for (int i = 0; i < data.length; i++) {
                temp[length - i - 1] = data[i];
            }
            result += bytesToHexString(temp, length, true);
        }
        return result;
    }
    public static String getHexString(byte[] data, boolean isBig) {
        String result = "0x";
        if (data == null) {
            return result;
        }
        int length = data.length;
        if (isBig) {
            result += bytesToHexString(data, length, false);
        } else {
            byte[] temp = new byte[length];
            for (int i = 0; i < data.length; i++) {
                temp[length - i - 1] = data[i];
            }
            result += bytesToHexString(temp, length, false);
        }
        return result;
    }

    public static String getHexString(byte[] data, int srartIndex, int len, boolean isBig) {
        String result = "";
        if (data == null) {
            return result;
        }
        byte[] temp = new byte[len];
        System.arraycopy(data, srartIndex, temp, 0, len);
        return getHexString(temp, isBig);
    }
    public static String byte2Hex(byte data) {
        int v = data & 0xFF;
        StringBuilder stringBuilder=new StringBuilder();
        String hv = Integer.toHexString(v).toUpperCase();
        if (hv.length() < 2) {
            stringBuilder.append(0);
        }
        stringBuilder.append(hv);
        return stringBuilder.toString();
    }


    /**
     * 将int转为高字节在前，低字节在后的byte数组（大端）
     *
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteBig(int n) {
        byte[] b = new byte[4];
        b[3] = (byte) (n & 0xff);
        b[2] = (byte) (n >> 8 & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[0] = (byte) (n >> 24 & 0xff);
        return b;
    }

    //需要使用2字节表示b
    public static String int2Hex16(String b) {
        Integer in = null;
        try {
            in = Integer.valueOf(b);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        if (in == null) {
            return "";
        }
        String s = Integer.toHexString(in).toUpperCase();
        if (s.length()==1) {
            return 0+s;
        }
        return s;
    }

    /**
     * 将int转为低字节在前，高字节在后的byte数组（小端）
     *
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteLittle(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        return b;
    }

    public static int bytes2Int(byte[] bytes, int startIndex, boolean isBig) {
        byte[] temp = new byte[4];
        System.arraycopy(bytes, startIndex, temp, 0, 4);
        if (isBig) {
            return bytes2IntBig(temp);
        } else {
            return bytes2IntLittle(temp);
        }
    }

    /**
     * byte数组到int的转换(小端)
     *
     * @param bytes
     * @return
     */
    public static int bytes2IntLittle(byte[] bytes) {
        int int1 = bytes[0] & 0xff;
        int int2 = (bytes[1] & 0xff) << 8;
        int int3 = (bytes[2] & 0xff) << 16;
        int int4 = (bytes[3] & 0xff) << 24;

        return int1 | int2 | int3 | int4;
    }

    /**
     * byte数组到int的转换(大端)
     *
     * @param bytes
     * @return
     */
    public static int bytes2IntBig(byte[] bytes) {
        int int1 = bytes[3] & 0xff;
        int int2 = (bytes[2] & 0xff) << 8;
        int int3 = (bytes[1] & 0xff) << 16;
        int int4 = (bytes[0] & 0xff) << 24;

        return int1 | int2 | int3 | int4;
    }

    public static byte[] long2Bytes(long l) {
        byte b[] = new byte[Long.SIZE];
        ByteBuffer buf = ByteBuffer.wrap(b);
        buf.putLong(l);
        buf.flip();
        return buf.array();
    }

    public static long bytesToLong(byte[] b) {
        ByteBuffer buf = ByteBuffer.wrap(b);
        return buf.getLong();
    }

    public static byte[] short2byte(short s) {
        byte[] b = new byte[2];
        for (int i = 0; i < 2; i++) {
            int offset = 16 - (i + 1) * 8; //因为byte占4个字节，所以要计算偏移量
            b[i] = (byte) ((s >> offset) & 0xff); //把16位分为2个8位进行分别存储
        }
        return b;
    }

    /**
     * 把byte转为字符串的bit
     */
    public static String byteToBit(byte b) {
        return ""
                + (byte) ((b >> 7) & 0x1) + "," + (byte) ((b >> 6) & 0x1) + ","
                + (byte) ((b >> 5) & 0x1) + "," + (byte) ((b >> 4) & 0x1) + ","
                + (byte) ((b >> 3) & 0x1) + "," + (byte) ((b >> 2) & 0x1) + ","
                + (byte) ((b >> 1) & 0x1) + "," + (byte) ((b >> 0) & 0x1);
    }

    public static short byte2short(Byte[] b) {
        short l = 0;
        for (int i = 0; i < 2; i++) {
            l <<= 8; //<<=和我们的 +=是一样的，意思就是 l = l << 8
            l |= (b[i] & 0xff); //和上面也是一样的  l = l | (b[i]&0xff)
        }
        return l;
    }

    public static short byte2short(byte[] b) {
        short l = 0;
        for (int i = 0; i < 2; i++) {
            l <<= 8; //<<=和我们的 +=是一样的，意思就是 l = l << 8
            l |= (b[i] & 0xff); //和上面也是一样的  l = l | (b[i]&0xff)
        }
        return l;
    }

    /**
     * bytes数组转为 short
     *
     * @param bytes 数组
     * @param start 起始位
     * @param isBig true:大端模式  false:小端模式
     * @return 短整型
     */
    public static short bytes2Short(byte[] bytes, int start, boolean isBig) {
        short value = 0;
        if (isBig) {
            value += (bytes[start] & 0x000000FF) << 8;
            value += (bytes[start + 1] & 0x000000FF);
        } else {
            value += (bytes[start] & 0x000000FF);
            value += (bytes[start + 1] & 0x000000FF) << 8;
        }
        return value;
    }

    /**
     * @param src
     * @param nLen
     * @return
     */
    public static String bytesToHexString(byte[] src, int nLen) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length && i < nLen; i++) {
            int v = src[i] & 0xFF;
            //stringBuilder.append("0x");
            //String hv = Integer.toHexString(v)
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
            stringBuilder.append(' ');
        }
        return stringBuilder.toString();
    }

    /**
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src, int nLen, boolean isTrim) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length && i < nLen; i++) {
            int v = src[i] & 0xFF;
            //stringBuilder.append("0x");
            //String hv = Integer.toHexString(v)
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
            if (!isTrim) {
                stringBuilder.append(' ');
            }
        }
        return stringBuilder.toString();
    }

    /**
     * @param src
     * @param nLen
     * @return
     */
    public static String bytesToHexString(byte[] src, int nLen, int printLen) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length && i < nLen; i++) {
            int v = src[i] & 0xFF;
            //stringBuilder.append("0x");
            //String hv = Integer.toHexString(v)
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
            stringBuilder.append(' ');

            if ((i + 1) % printLen == 0) {
                stringBuilder.append("\n");
            }
        }
        return stringBuilder.toString();
    }
    /**
     * @param src
     * @param nLen
     * @return
     */
    public static String bytesToHexString(byte[] src, int startIndex,int nLen, int printLen) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = startIndex; i < src.length && i < startIndex+nLen; i++) {
            int v = src[i] & 0xFF;
            //stringBuilder.append("0x");
            //String hv = Integer.toHexString(v)
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
            stringBuilder.append(' ');

            if ((i + 1) % printLen == 0) {
                stringBuilder.append("\n");
            }
        }
        return stringBuilder.toString();
    }

    /**
     * @param src
     * @return
     */
    public static String byteToHexString(byte src) {
        StringBuilder stringBuilder = new StringBuilder("");
        int v = src & 0xFF;
        //stringBuilder.append("0x");
        //String hv = Integer.toHexString(v)
        String hv = Integer.toHexString(v).toUpperCase();
        if (hv.length() < 2) {
            stringBuilder.append(0);
        }
        stringBuilder.append(hv);
        stringBuilder.append(' ');
        return stringBuilder.toString();
    }

}
